MyControlDefProc
CHANGED WITH THE APPEARANCE MANAGER
If you wish to define new, nonstandard controls for your application, you must write a control definition function and store it in a resource file as a resource of type'CDEF'
.The Control Manager declares the type for an application-defined control definition function as follows:
typedef pascal SInt32 (*ControlDefProcPtr) (SInt16 varCode, ControlHandle theControl, ControlDefProcMessage message, SInt32 param);The Control Manager defines the data typeControlDefUPP
to identify the universal procedure pointer for this application-defined function:
typedef UniversalProcPtr ControlDefUPP;You typically use theNewControlDefProc
macro like this:
ControlDefUPP myControlDefUPP; myControlDefUPP = NewControlDefProc (MyControl);You typically use theCallControlDefProc
macro like this:
CallControlDefProc(myControlDefUPP, varCode, theControl, message, param);Here's how to declare the functionMyControlDefProc
:
pascal SInt32 MyControlDefProc ( SInt16 varCode, ControlHandle theControl, ControlDefProcMessage message, SInt32 param);
varCode
- The control's variation code.
theControl
- A handle to the control that the operation will affect.
message
- A code for the task to be performed. The
message
parameter contains one of the task codes defined in "Messages". The subsections that follow explain each of these tasks in detail.param
- Data associated with the task specified by the
message
parameter. If the task requires no data, this parameter is ignored.- function result
- The function results that your control definition function returns depend on the value that the Control Manager passes in the
message
parameter.DISCUSSION
The Control Manager calls your control definition function under various circumstances; the Control Manager uses themessage
parameter to inform your control definition function what action it must perform. The data that the Control Manager passes in theparam
parameter, the action that your control definition function must undertake, and the function results that your control definition function returns all depend on the value that the Control Manager passes in themessage
parameter. The rest of this section describes how to respond to the various values that the Control Manager passes in themessage
parameter.Messages
The Control Manager passes constants of typeControlDefProcMessage
to indicate the action your control definition function must perform.
enum { drawCntl = 0, testCntl = 1, calcCRgns = 2, initCntl = 3, dispCntl = 4, posCntl = 5, thumbCntl = 6, dragCntl = 7, autoTrack = 8, calcCntlRgn = 10, calcThumbRgn = 11, kControlMsgDrawGhost = 13, kControlMsgCalcBestRect = 14, kControlMsgHandleTracking = 15, kControlMsgFocus = 16, kControlMsgKeyDown = 17, kControlMsgIdle = 18, kControlMsgGetFeatures = 19, kControlMsgSetData = 20, kControlMsgGetData = 21, kControlMsgActivate = 22, kControlMsgSetUpBackground = 23, kControlMsgSubValueChanged = 25, kControlMsgCalcValueFromPos = 26, kControlMsgTestNewMsgSupport = 27, kControlMsgSubControlAdded = 28, kControlMsgSubControlRemoved = 29 }; typedef SInt16 ControlDefProcMessage;Constant descriptions
drawCntl
- Draw the entire control or part of a control.
testCntl
- Test where the mouse has been pressed.
calcCRgns
- Calculate the region for the control or the indicator in 24-bit systems. This message is obsolete in Mac OS 7.6 and later.
initCntl
- Perform additional control initialization.
dispCntl
- Perform additional control disposal actions.
posCntl
- Move and update the indicator setting.
thumbCntl
- Calculate the parameters for dragging the indicator.
dragCntl
- Perform customized dragging (of the control or its indicator).
autoTrack
- Execute the specified action function.
calcCntlRgn
- Calculate the control region in 32-bit systems.
calcThumbRgn
- Calculate the indicator region in 32-bit systems.
kControlMsgDrawGhost
- Draw a ghost image of the indicator.
kControlMsgCalcBestRect
- Calculate the optimal control rectangle.
kControlMsgHandleTracking
- Perform custom tracking.
kControlMsgFocus
- Handle keyboard focus.
kControlMsgKeyDown
- Handle keyboard events.
kControlMsgIdle
- Perform idle processing.
kControlMsgGetFeatures
- Specify which Appearance-compliant messages are supported.
kControlMsgSetData
- Set control-specific data.
kControlMsgGetData
- Get control-specific data.
kControlMsgActivate
- Handle activate and deactivate events.
kControlMsgSetUpBackground
- Set the control's background color or pattern (only available if the control supports embedding).
kControlMsgSubValueChanged
- Be informed that the value of a subcontrol embedded in the control has changed; this message is useful for radio groups. Only available with Appearance 1.0.1 and later.
kControlMsgCalcValueFromPos
- Support live feedback while dragging the indicator and calculate the control value based on the new indicator region.
kControlMsgTestNewMsgSupport
- Specify whether Appearance-compliant messages are supported.
kControlMsgSubControlAdded
- Be informed that a subcontrol has been embedded in the control. This message is only available with Appearance 1.0.1 and later.
kControlMsgSubControlRemoved
- Be informed that a subcontrol is about to be removed from the control. This message is only available with Appearance 1.0.1 and later.
Only the following messages will be sent to your control definition function:
WHEN THE APPEARANCE MANAGER IS NOT AVAILABLE
drawCntl = 0, testCntl = 1, calcCRgns = 2, initCntl = 3, dispCntl = 4, posCntl = 5, thumbCntl = 6, dragCntl = 7, autoTrack = 8, calcCntlRgn = 10, calcThumbRgn = 11Drawing the Control or Its Part
When the Control Manager passes the valuedrawCntl
in themessage
parameter, your control definition function should respond by drawing the indicator or the entire control.The Control Manager passes one of the following drawing constants in the low word of the
param
parameter to specify whether the user is drawing an indicator or the whole control. The high-order word of theparam
parameter may contain undefined data; therefore, evaluate only the low-order word of this parameter.
enum { kDrawControlEntireControl = 0, kDrawControlIndicatorOnly = 129 };Constant descriptions
With the exception of part code 128, which is reserved for future use and should not be used, any other value indicates a part code for the control.
kDrawControlEntireControl
- Draw the entire control.
kDrawControlIndicatorOnly
- Draw the indicator only.
If the specified control is visible, your control definition function should draw the control (or the part specified in the
param
parameter) within the control's rectangle. If the control is invisible (that is, if itscontrlVis
field is set to 0), your control definition function does nothing.When drawing the control or its part, take into account the current values of its
contrlHilite
andcontrlValue
fields in the control structure.If the part code for your control's indicator is passed in
param
, assume that the indicator hasn't moved; the Control Manager, for example, may be calling your control definition function so that you may simply highlight the indicator. However, when your application callsSetControlValue
,SetControlMinimum
, andSetControlMaximum
, they in turn may call your control definition function with thedrawCntl
message to redraw the indicator. Since these functions have no way of determining what part code you chose for your indicator, they all pass 129 inparam
, meaning that you should move your indicator. Your control definition function must detect this part code as a special case and remove the indicator from its former location before drawing it. If your control has more than one indicator, you should interpret 129 to mean all indicators.When sent the message
drawCntl
, your control definition function should return 0 as its function result.Testing Where the Mouse-Down Event Occurs
When the Control Manager passes the value for thetestCntl
constant in themessage
parameter, your control definition function should respond by determining whether a specified point is in a visible control.The Control Manager passes a point (in local coordinates) in the
param
parameter. The point's vertical coordinate is contained in the high-order word of the long integer, and horizontal coordinate is contained in the low-order word.Your control definition function should return the part code of the part that contains the specified point; it should return 0 if the point is outside the control or if the control is inactive.
Calculating the Control and Indicator Regions on 24-Bit Systems
When the Control Manager passes the value for thecalcCRgns
constant in themessage
parameter, your control definition function should calculate the region passed in theparam
parameter for the specified control or its indicator.The Control Manager passes a QuickDraw region handle in the
param
parameter. If the high-order bit ofparam
is set, the region requested is that of the control's indicator; otherwise, the region requested is that of the entire control. Your control definition function should clear the high bit of the region handle before calculating the region.When passed this message, your control definition function should always return 0, and it should express the region in the local coordinate system of the control's window.
- IMPORTANT
- The
calcCRgns
message will never be sent to any system running on 32-bit mode and is therefore obsolete in Mac OS 7.6 and later. ThecalcCntlRgn
andcalcThumbRgn
messages will be sent instead.![]()
Calculating the Control and Indicator Regions on 32-Bit Systems
When the Control Manager passes the values for thecalcCntlRgn
orcalcThumbRgn
constants in themessage
parameter, your control definition function should calculate the region for the specified control or its indicator using the QuickDraw region handle passed in theparam
parameter .If the Control Manager passes the value for the
calcThumbRgn
constant in themessage
parameter, calculate the region occupied by the indicator. If the Control Manager passes the value for thecalcCntlRgn
constant in themessage
parameter, calculate the region for the entire control.When passed this message, your control definition function should always return 0, and it should express the region in the local coordinate system of the control's window.
Performing Additional Control Initialization
After initializing fields of a control structure as appropriate when creating a new control, the Control Manager passesinitCntl
in themessage
parameter to give your control definition function the opportunity to perform any type-specific initialization you may require. For example, the standard control definition function for scroll bars allocates space for a region to hold the scroll box and stores the region handle in thecontrlData
field of the new control structure.When passed the value for the
initCntl
constant in themessage
parameter, your control definition function should ignore theparam
parameter and return 0 as a function result.Performing Additional Control Disposal Actions
The functionDisposeControl
passesdispCntl
in themessage
parameter to give your control definition function the opportunity to carry out any additional actions when disposing of a control. For example, the standard definition function for scroll bars releases the memory occupied by the scroll box region, whose handle is kept in thecontrlData
field of the control structure.When passed the value for the
dispCntl
constant in themessage
parameter, your control definition function should ignore theparam
parameter and return 0 as a function result.Dragging the Control or Its Indicator
When a mouse-up event occurs in the indicator of a control, theHandleControlClick
orTrackControl
functions call your control definition function and passposCntl
in themessage
parameter. In this case, the Control Manager passes a point (in coordinates local to the control's window) in theparam
parameter that specifies the vertical and horizontal offset, in pixels, by which your control definition function should move the indicator from its current position. Typically, this is the offset between the points where the cursor was when the user pressed and released the mouse button while dragging the indicator. The point's vertical offset is contained in the high-order word of theparam
parameter, and its horizontal offset is contained in the low-order word.Your definition function should calculate the control's new setting based on the
given offset and then, to reflect the new setting, redraw the control and update thecontrlValue
field in the control structure. Your control definition function should ignore theparam
parameter and return 0 as a function result.Calculating Parameters for Dragging the Indicator
When the Control Manager passes the value forthumbCntl
in themessage
parameter, your control definition function should respond by calculating values analogous to thelimitRect
,slopRect
, andaxis
parameters ofDragControl
that constrain how the indicator is dragged. On entry, the fieldsparam->limitRect.top
andparam->limitRect.left
contain the point where the mouse-down event first occurred.The Control Manager passes a pointer to a structure of type
IndicatorDragConstraint
in theparam
parameter:
struct IndicatorDragConstraint { Rect limitRect; Rect slopRect; DragConstraint axis; }; typedef struct IndicatorDragConstraint IndicatorDragConstraint; typedef IndicatorDragConstraint *IndicatorDragConstraintPtr; typedef IndicatorDragConstraintPtr *IndicatorDragConstraintHandle;Your definition function should store the appropriate values into the fields of the structure pointed to by the
Field Description
limitRect
- A pointer to a rectangle--whose coordinates should normally coincide with or be contained in the window's content region--delimiting the area in which the user can drag the control's outline.
slopRect
- A pointer to a rectangle that allows some extra space for the user to move the mouse while still constraining the control within the rectangle specified in the
limitRect
parameter.axis
- The axis along which the user may drag the control's outline.
param
parameter; they're analogous to the similarly named parameters of the Window Manager functionDragGrayRgn
.
- Your control definition function should return 0 as function result.
Performing Custom Dragging
When the Control Manager passes the value for thedragCntl
constant in themessage
parameter, theparam
parameter typically contains a custom dragging constant with one of the following values to specify whether the user is dragging an indicator or the whole control:
enum { kDragControlEntireControl = 0, kDragControlIndicator = 1 };Constant descriptions
If you want to use the Control Manager's default method of dragging, which is to call
kDragControlEntireControl
- Dragging the entire control.
kDragControlIndicator
- Dragging the indicator.
- Note
- When the Appearance Manager is present, the message
kControlMsgHandleTracking
should be sent instead ofdragCntl
to handle any custom tracking; see "Performing Custom Tracking".![]()
DragControl
to drag the control or the Window Manager functionDragGrayRgn
to drag its indicator, return 0 as the function result for your control definition function.If your control definition function returns a nonzero value, your control definition function (not the Control Manager) must drag the specified control (or its indicator) to follow the cursor until the user releases the mouse button. If the user drags the entire control, your definition function should use the function
MoveControl
to reposition the control to its new location after the user releases the mouse button. If the user drags the indicator, your definition function must calculate the control's new setting (based on the pixel offset between the points where the cursor was when the user pressed and released the mouse button while dragging the indicator) and then, to reflect the new setting, redraw the control and update thecontrlValue
field in the control structure. Note that, in this case, the functionsHandleControlClick
andTrackControl
return 0 whether or not the user changes the indicator's position. Thus, you must determine whether the user has changed the control's setting by another method, for instance, by comparing the control's value before and after the call toHandleControlClick
.Executing an Action Function
The only way to specify actions in response to all mouse-down events in a control or its indicator is to define your own control definition function that specifies an action function. When you create the control, your control definition function must first respond to theinitCntl
message by storing(ControlDefUPP)-1L
in thecontrlAction
field of the control structure. (The Control Manager sends theinitCntl
message to your control definition function after initializing the fields of a new control structure.) Then, when your application passes(ControlActionUPP)-1L
in theactionProc
parameter ofHandleControlClick
orTrackControl
,HandleControlClick
calls your control definition function with theautoTrack
message. The Control Manager passes the part code of the part where the mouse-down event occurs in theparam
parameter. Your control definition function should then use this information to respond as an action function would.
If the mouse-down event occurs in an indicator of a control that supports live feedback, your action function should take two parameters (a handle to the control and the part code of the control where the mouse-down event first occurred). This action function is the same one you would use to define actions to be performed in control part codes in response to a mouse-down event; see
- Note
- For the
autoTrack
message, the high-order word of theparam
parameter may contain undefined data; therefore, evaluate only the low-order word of this parameter.![]()
MyActionProc
.If the mouse-down event occurs in an indicator of a control that does not support live feedback, your action function should take no parameters, because the user may move the cursor outside the indicator while dragging it; see
MyIndicatorActionProc
.Specifying Whether Appearance-Compliant Messages Are Supported
If your control definition function supports Appearance-compliant messages, it should returnkControlSupportsNewMessages
as a function result when the Control Manager passeskControlMsgTestNewMsgSupport
in themessage
parameter.
enum{ kControlSupportsNewMessages = ' ok ' };Constant description
kControlSupportsNewMessages
The control definition function supports new messages introduced with Mac OS 8 and the Appearance Manager.Specifying Which Appearance-Compliant Messages Are Supported
If your control definition function supports Appearance-compliant messages, it should return a bit field of the features it supports in response to thekControlMsgGetFeatures
message. Your control definition function should ignore theparam
parameter.The bit field returned by your control definition function should be composed of one or more of the following bits:
enum{ kControlSupportsGhosting = 1 << 0, kControlSupportsEmbedding = 1 << 1, kControlSupportsFocus = 1 << 2, kControlWantsIdle = 1 << 3, kControlWantsActivate = 1 << 4, kControlHandlesTracking = 1 << 5, kControlSupportsDataAccess = 1 << 6, kControlHasSpecialBackground = 1 << 7, kControlGetsFocusOnClick = 1 << 8, kControlSupportsCalcBestRect = 1 << 9, kControlSupportsLiveFeedback = 1 << 10, kControlHasRadioBehavior = 1 << 11 };Constant descriptions
kControlSupportsGhosting
- If this bit (bit 0) is set, the control definition function supports the
kControlMsgDrawGhost
message.kControlSupportsEmbedding
- If this bit (bit 1) is set, the control definition function supports the
kControlMsgSubControlAdded
andkControlMsgSubControlRemoved
messages.kControlSupportsFocus
- If this bit (bit 2) is set, the control definition function supports the
kControlMsgKeyDown
message. If this bit and thekControlGetsFocusOnClick
bit are set, the control definition function supports thekControlMsgFocus
message.kControlWantsIdle
- If this bit (bit 3) is set, the control definition function supports the
kControlMsgIdle
message.kControlWantsActivate
- If this bit (bit 4) is set, the control definition function supports the
kControlMsgActivate
message.kControlHandlesTracking
- If this bit (bit 5) is set, the control definition function supports the
kControlMsgHandleTracking
message.kControlSupportsDataAccess
- If this bit (bit 6) is set, the control definition function supports the
kControlMsgGetData
andkControlMsgSetData
messages.kControlHasSpecialBackground
- If this bit (bit 7) is set, the control definition function supports the
kControlMsgSetUpBackground
message.kControlGetsFocusOnClick
- If this bit (bit 8) and the
kControlSupportsFocus
bit are set, the control definition function supports thekControlMsgFocus
message.kControlSupportsCalcBestRect
- If this bit (bit 9) is set, the control definition function supports the
kControlMsgCalcBestRect
message.kControlSupportsLiveFeedback
- If this bit (bit 10) is set, the control definition function supports the
kControlMsgCalcValueFromPos
message.kControlHasRadioBehavior
- If this bit (bit 11) is set, the control definition function supports radio button behavior and can be embedded in a radio group control. This constant is available with Appearance 1.0.1 and later.
If your control definition function supports indicator ghosting, it should return
Drawing a Ghost Image of the Indicator
kControlSupportsGhosting
as one of the feature bits in response to akControlMsgGetFeatures
message. If this bit is set and the control indicator is being tracked, the Control Manager calls your control definition function and passeskControlMsgDrawGhost
in themessage
parameter. A handle to the region where the ghost should be drawn will be passed in theparam
parameter.Your control definition function should respond by redrawing the control with the ghosted indicator at the specified location and should return 0 as its function result.
- Note
- The ghost indicator should always be drawn before the actual indicator so that it appears underneath the actual indicator.
![]()
Calculating the Optimal Control Rectangle
If your control definition function supports calculating the optimal dimensions of the control rectangle, it should returnkControlSupportsCalcBestRect
as one of the feature bits in response to thekControlMsgGetFeatures
message. If this bit is set andGetBestControlRect
is called, the Control Manager will call your control definition function and passkControlMsgCalcBestRect
in themessage
parameter. The Control Manager passes a pointer to a control size calculation structure in theparam
parameter.Your control definition function should respond by calculating the width and height of the optimal control rectangle and adjusting the rectangle by setting the
height
andwidth
fields of the control size calculation structure to the appropriate values. If your control definition function displays text, it should pass in the offset from the bottom of control to the base of the text in the baseLine field of the structure. Your control definition function should return the offset value stored in the structure'sbaseLine
field.The control size calculation structure is a structure of type
ControlCalcSizeRec
:
struct ControlCalcSizeRec { SInt16 height; SInt16 width; SInt16 baseLine; }; typedef struct ControlCalcSizeRec ControlCalcSizeRec; typedef ControlCalcSizeRec *ControlCalcSizePtr;
Field Description
height
- The optimal height (in pixels) of the control's bounding rectangle.
width
- The optimal width (in pixels) of the control's bounding rectangle.
baseLine
- The offset from the bottom of the control to the base of the text. This value is generally negative.
Performing Custom Tracking
If your control definition function supports custom tracking, it should returnkControlHandlesTracking
as one of the feature bits in response to akControlMsgGetFeatures
message. If this bit is set and a mouse-down event occurs in your control,TrackControl
orHandleControlClick
calls your control definition function and passeskControlMsgHandlesTracking
in themessage
parameter. The Control Manager passes a pointer to a control tracking structure in theparam
parameter. Your control definition function should respond appropriately and return the part code that was hit, orkControlNoPart
if the mouse-down event occurred outside the control; see "Control Part Code Constants".The control tracking structure is a structure of type
ControlTrackingRec
:
struct ControlTrackingRec { Point startPt; SInt16 modifiers; ControlActionUPP action; }; typedef struct ControlTrackingRec ControlTrackingRec; typedef ControlTrackingRec *ControlTrackingPtr;
Field Description
startPt
- The location of the cursor at the time the mouse button was first pressed, in local coordinates. Your application retrieves this point from the
where
field of the event structure.modifiers
- The constant in the
modifiers
field of the event structure specifying the state of the modifier keys and the mouse button at the time the event was posted.action
- A pointer to an action function defining what action your application takes while the user holds down the mouse button. The value of the
actionProc
parameter can be a validprocPtr
,nil
, or -1. A value of -1 indicates that the control should either perform auto tracking, or if it is incapable of doing so, do nothing (likenil
).Handling Keyboard Focus
If your control definition function can change its keyboard focus, it should setkControlSupportsFocus
andkControlGetsFocusOnClick
as feature bits in response to akControlMsgGetFeatures
message. If these bits are set and theAdvanceKeyboardFocus
,ReverseKeyboardFocus
,ClearKeyboardFocus
, orSetKeyboardFocus
function is called, the Control Manager calls your control definition function and passeskControlMsgFocus
in themessage
parameter.The Control Manager passes one of the control focus part code constants described below or a valid part code in the
param
parameter. Your control definition function should respond by adjusting the focus accordingly.Your control definition function should return the control focus part code or actual control part that was focused on. Return
kControlFocusNoPart
if your control does not accept focus or has just relinquished it. Return a nonzero part code to indicate that your control received keyboard focus. Your control definition function is responsible for maintaining which part is focused.
enum { kControlFocusNoPart = 0, kControlFocusNextPart = -1, kControlFocusPrevPart = -2 }; typedef SInt16 ControlFocusPart;Constant descriptions
kControlFocusNoPart
- Your control definition function should relinquish its focus and return
kControlFocusNoPart
. It might respond by deactivating its text edit handle and erasing its focus ring. If the control is at the end of its subparts, it should returnkControlFocusNoPart
. This tells the focusing mechanism to jump to the next control that supports focus.kControlFocusNextPart
- Your control definition function should change keyboard focus to its next part, the entire control, or remove keyboard focus from the control, depending upon the circumstances.
For multiple part controls that already had keyboard focus, the next part of the control would receive keyboard focus whenkControlFocusNextPart
was passed in theparam
parameter. For example, a clock control with keyboard focus would change its focus to the left-most element of the control (the month field).
For single-part controls that did not have keyboard focus and are now receiving it, the entire control would receive keyboard focus whenkControlFocusNextPart
was passed in theparam
parameter.
For single-part controls that already had keyboard focus and are now losing it, the entire control would lose keyboard focus.
If you are passedkControlFocusNextPart
and have run out of parts, returnkControlFocusNoPart
to indicate that the user tabbed past the control.kControlFocusPrevPart
- Your control definition function should change keyboard focus to its previous part, the entire control, or remove keyboard focus from the control, depending upon the circumstances.
For multiple part controls that already had keyboard focus, the previous part of the control would receive keyboard focus whenkControlFocusPrevPart
was passed in theparam
parameter. For example, a clock control with keyboard focus would change its focus to the right-most element of the control (the year field).
For single-part controls that did not have keyboard focus and are now receiving it, the entire control would receive keyboard focus whenkControlFocusNextPart
was passed in theparam
parameter.
For single-part controls that already had keyboard focus and are now losing it, the entire control would lose keyboard focus.
If you are passedkControlFocusPrevPart
and have run out of parts, returnkControlFocusNoPart
to indicate that the user tabbed past the control.<part code>
- Your control definition function should focus on the specified part code. Your function can interpret this in any way it wishes.
Handling Keyboard Events
If your control definition function can handle keyboard events, it should returnkControlSupportsFocus
--every control that supports keyboard focus must also be able to handle keyboard events--as one of the feature bits in response to akControlMsgGetFeatures
message. If this bit is set, the Control Manager will passkControlMsgKeyDown
in themessage
parameter. The Control Manager passes a pointer to a control key down structure in theparam
parameter. Your control definition function should respond by processing the keyboard event as appropriate and return 0 as the function result.The control key down structure is a structure of type
ControlKeyDownRec
:
struct ControlKeyDownRec { SInt16 modifiers; SInt16 keyCode; SInt16 charCode; }; typedef struct ControlKeyDownRec ControlKeyDownRec; typedef ControlKeyDownRec *ControlKeyDownPtr;
Field Description
modifiers
- The constant in the
modifiers
field of the event structure specifying the state of the modifier keys and the mouse button at the time the event was posted.keyCode
- The virtual key code derived from the event structure. This value represents the key pressed or released by the user. It is always the same for a specific physical key on a particular keyboard regardless of which modifier keys were also pressed.
charCode
- A particular character derived from the event structure. This value depends on the virtual key code, the state of the modifier keys, and the current
'KCHR'
resource.Performing Idle Processing
If your control definition function can perform idle processing, it should returnkControlWantsIdle
as one of the feature bits in response to akControlMsgGetFeatures
message. If this bit is set andIdleControls
is called for the window your control is in, the Control Manager will passkControlMsgIdle
in themessage
parameter. Your control definition function should ignore theparam
parameter and respond appropriately. For example, indeterminate progress indicators and asynchronous arrows use idle time to perform their animation.Your control definition function should return 0 as the function result.
Getting and Setting Control-Specific Data
If your control definition function supports getting and setting control-specific data, it should returnkControlSupportsDataAccess
as one of its features bits in response to thekControlMsgGetFeatures
message. If this bit is set, the Control Manager will call your control definition function and passkControlMsgSetData
in themessage
parameter whenSetControlData
is called, and will passkControlMsgGetData
in themessage
parameter whenGetControlData
andGetControlDataSize
are called. The Control Manager passes a pointer to a control data access structure in theparam
parameter. Your definition function should respond by filling out the structure and returning an operating system status message as the function result.
The control data access structure is a structure of type ControlDataAccessRec: struct ControlDataAccessRec{ ResType tag; ResType part; Size size; Ptr dataPtr; }; typedef struct ControlDataAccessRec ControlDataAccessRec; typedef ControlDataAccessRec *ControlDataAccessPtr;
Field Description
tag
- A constant representing a piece of data that is passed in (in response to a
kControlMsgSetData
message) or returned (in response to akControlMsgGetData
message); see "Control Data Tag Constants" for a description of these constants. The control definition function should returnerrDataNotSupported
if the value in thetag
parameter is unknown or invalid.part
- The part of the control that this data should be applied to. If the information is not tied to a specific part of the control or the control has no parts, pass 0.
size
- On entry, the size of the buffer pointed to by the
dataPtr
field. In response to akControlMsgGetData
message, this field should be adjusted to reflect the actual size of the data that the control is maintaining. If the size of the buffer being passed in is smaller than the actual size of the data, the control definition function should returnerrDataSizeMismatch
.dataPtr
- A pointer to a buffer to read or write the information requested. In response to a
kControlMsgGetData
message, this field could benil
, indicating that you wish to return the size of the data in thesize
field.Handling Activate and Deactivate Events
If your control definition function wants to be informed whenever it is being activated or deactivated, it should returnkControlWantsActivate
as one of the feature bits in response to thekControlMsgGetFeatures
message. If this bit is set and your control definition function is being activated or deactivated, the Control Manager calls it and passeskControlMsgActivate
in themessage
parameter. The Control Manager passes a 0 or 1 in theparam
parameter. A value of 0 indicates that the control is being deactivated; 1 indicates that it is being activated.Your control definition function should respond by performing any special processing before the user pane becomes activated or deactivated, such as deactivating its
TEHandle
orListHandle
if it is about to be deactivated.Your control definition function should return 0 as the function result.
Setting a Control's Background Color or Pattern
If your control definition function supports embedding and draws its own background, it should returnkControlHasSpecialBackground
as one of the feature bits in response to thekControlMsgGetFeatures
message. If this bit is set and an embedding hierarchy of controls is being drawn in your control, the Control Manager passeskControlMsgSetUpBackground
in themessage
parameter of your control definition function. The Control Manager passes a pointer to a filled-in control background structure in theparam
parameter. Your control definition function should respond by setting its background color or pattern to whatever is appropriate given the bit depth and device type passed in. Your control definition function should return 0 as the function result.The control background structure is a structure of type
ControlBackgroundRec
:
struct ControlBackgroundRec { SInt16 depth; Boolean colorDevice; }; typedef struct ControlBackgroundRec ControlBackgroundRec; typedef ControlBackgroundRec *ControlBackgroundPtr;
Field Description
depth
- A signed 16-bit integer indicating the bit depth (in pixels) of the current graphics port.
colorDevice
- A Boolean value. If
true
,you are drawing on a color device. If
false
, you are drawing on a monochrome device.Supporting Live Feedback
If your control definition function supports live feedback while tracking the indicator, it should returnkControlSupportsLiveFeedback
as one of the feature bits in response to thekControlMsgGetFeatures
message. If this bit is set, the Control Manager will call your control definition function when it tracks the indicator and passkControlMsgCalcValueFromPos
in themessage
parameter. The Control Manager passes a handle to the indicator region being dragged in theparam
parameter.Your control definition function should respond by calculating its value and drawing the control based on the new indicator region passed in. Your control definition function should not recalculate its indicator position. After the user is done dragging the indicator, your control definition function will be called with a
posCntl
message at which time you can recalculate the position of the indicator. Not recalculating the indicator position each time your control definition function is called creates a smooth dragging experience for the user.Your control definition function should return 0 as the function result.
Being Informed When Subcontrols Are Added or Removed
If your control definition function wishes to be informed when subcontrols are added or removed, it should returnkControlSupportsEmbedding
as one of the feature bits in response to thekControlMsgGetFeatures
message. If this bit is set, the Control Manager passesControlMsgSubControlAdded
in themessage
parameter immediately after a subcontrol is added, or it passeskControlMsgSubControlRemoved
just before a subcontrol is removed from your embedder control. A handle to the control being added or removed from the embedding hierarchy is passed in theparam
parameter. Your control definition function should respond appropriately and return 0 as the function result.Typically, a control definition function only supports this message if it wants to do extra processing in response to changes in its embedded controls. Radio groups use these messages to perform necessary processing for handling embedded controls. For example, if a currently selected radio button is deleted, the group can adjust itself accordingly.